# 函数

# 1.定义
'''
def 函数名(参数1,参数2,...):
    函数体
    return 值
'''


# 2.返回值
# 返回多个值时用逗号隔开，返回形式为元组
def func():
    return 1, 2, 3


print(func(), type(func()))


# 3.参数
# 位置参数 x,y
def func1(x, y):
    pass


func1(1, 2)  # 按位置传参

# 关键字参数（实参） x,y
func1(y=1, x=3)  # 使用关键字传参

# 位置和关键字混合传参 但是不能重复传参，位置实参不能才关键字实参之后
func1(3, y=3)


# 默认参数 在定义阶段就默认赋值，调用时可以不用传参
def func2(x, y=3):
    pass


func2(1)


# 默认参数可以是任意数据类型，但是不推荐使用可变类型，一般采用以下方法
def func3(x, y, l=None):
    if l is None:  # 因为None内存中只有一个，推荐使用is判断
        l = []
    pass


# 可变长度参数
# *接受溢出的位置形参
def func4(x, *args):
    print("*接受溢出的位置形参", x, args)


func4(1, 2, 3, 4)  # 多余的参数会有*存储为元组赋值给args变量 （默认使用args变量名接收*）


# *接受溢出的位置实参
def func4(x, y, z):
    print("*接受溢出的位置实参", x, y, z)


l = [2, 3]
func4(1, *l)  # *实参会将数据通过for循环进行拆解


# **接受溢出的位置形参
def func5(x, **kwargs):
    print("**接受溢出的关键字形参", x, kwargs)


func5(x=1, y=2, z=3, a=4)  # 多余的参数会有**存储为字典赋值给kwargs变量 （默认使用kwargs变量名接收**）


# **接受溢出的位置实参
def func5(x, y, z):
    print("**接受溢出的关键字实参", x, y, z)


kw = {"y": 2, "z": 3}
func5(x=1, **kw)  # **实参会将数据通过for循环进行拆解为键值对


# *和**混合使用 * 必须在 ** 前面
def func6(x, *args, **kwargs):
    print(x, args, kwargs)


func6(1, 2, 3, y=4, z=5, a=6)  # 多余的参数会有**存储为字典赋值给kwargs变量 （默认使用kwargs变量名接收**）


# 默认类型提示（python3.5以上）类型提示只是自己定义的规范，依然可以随意传值
# :后面是提示信息，可以随意写name: “传入姓名  ” = "roy",
def func8(name: str = "roy", age: int = 18, hobbies: tuple = ("music", "game")) -> int:
    print(name)
    print(age)
    print(hobbies)
    return 11
res=func8(1,2,3)  # 依然可以随意传值
print(res)
